#!/usr/bin/env python
import os.path
import getopt
import sys
import ConfigParser

CONFIG=os.path.expanduser("~") + "/.ssh/magic"

class HostSettings(object):
	def __init__(self, config, userhost, override=False):
		self.config = config
		user, alias = self.split_host(userhost)
		self.host = self.find_host(alias)
		config_user = self.find_user(self.host)
		self.port = self.find_port(self.host)
		self.user = config_user
		if user and (not config_user or override):
			self.save_user(user)
			self.user = user

	def __str__(self):
		rep = ""
		if self.port:
			rep += "-p " + self.port + " "
		if self.user:
			rep += self.user + "@"
		rep += str(self.host)
		return rep
		
	def split_host(self, userhost):
		if userhost.find('@') != -1:
			user, alias = userhost.split('@')
		else:
			user = False
			alias = userhost
		return (user,alias)
		
	def find_host(self, alias):
		host = False
		while self.config.has_section(alias) and not host:
			if self.config.has_option(alias, "alias"):
				alias = self.config.get(alias, "alias")
			else:
				host = alias	
		if not host:
			self.config.add_section(alias)
			return alias
		return host
		
	def find_user(self, host):
		user = False
		if self.config.has_option(host, "user"):
			user = self.config.get(host, "user")
		return user
		
	def find_port(self, host):
		port = False
		if self.config.has_option(host, "port"):
			port = self.config.get(host, "port")
		return port
		
	def save_user(self, user, override=False):
		self.config.set(self.host, "user", user)

	def save_port(self, port, override=False):
		if not self.port or override:
			self.config.set(self.host, "port", port)
		self.port = port

	def save_alias(self, alias, override=False):
		if not self.config.has_section(alias):
			self.config.add_section(alias)
			self.config.set(alias, "alias", self.host) 
		elif override:
			self.config.remove_section(alias)
			self.config.add_section(alias)
			self.config.set(alias, "alias", self.host) 

	def save(self):
		self.config.write(open(CONFIG, 'w'))
		
def main():
	optlist,args = getopt.getopt(sys.argv[1:], "oka:p:S")

	configFileJustCreated = False
	if not os.path.isfile(CONFIG):
		tempfilehandle = open(CONFIG,'w')
		tempfilehandle.close()
		configFileJustCreated = True

	config = ConfigParser.ConfigParser()
	configfile = open(CONFIG)
	config.readfp(configfile)
	configfile.close()
		
	if ('-S','') in optlist or configFileJustCreated:
		setup(config)
		
	if len(args) != 1:
	   usage()

	override=False
	if ('-o','') in optlist:
		override=True
	host_settings = HostSettings(config, args[0], override)

	port_list = filter(lambda x: x[0] == '-p', optlist)
	if port_list:
		host_settings.save_port(port_list[0][1], override)

	alias_list = filter(lambda x: x[0] == '-a', optlist)
	if alias_list:
		host_settings.save_alias(alias_list[0][1], override)

	host_settings.save()

	if config.get("options", "agent") == 'yes':
		start_agent()

	# this could be better.
	# it could check if the key is already there.
	if ('-k','') in optlist:
		print "ssh-copy-id", host_settings

	print "ssh", host_settings


def ask_question(question, default=True):
	defaultstr = " y/N : "
	if default:
		defaultstr = " Y/n : "
	answer = None
	while not answer:
		response = raw_input(question + defaultstr).strip().lower()
		if (not response and default) or response in ('yes', 'y'):
			answer = 'yes'
		elif (not response and not default) or response in ('no', 'n'):
			answer = 'no'
		else:
			pass
	return answer

def setup(config):
	agent = ask_question("Should ssh-agent be started for you?")
	config.set("options", "agent", agent)
def usage():
	print "Usage: magicssh -okS [-a alias][-p port] [user@]{system|alias}"
	print "       -o = override previous alias, user, or port setting"
	print "       -k = copy key to system"
	print "       -S = rerun Setup"
	print "       -a = save this alias for this system"
	print "       -p = port to ssh to"
	print ""
	print "example: first: magicssh -a foo -p 444 bar@baz.system"
	print "         next: magicssh foo"
	print "         you'll get to the same place."
	
	sys.exit(5)
def start_agent():
	"""prints shell commands to start an ssh agent"""
	commands="""ssh-add -l  >& /dev/null

case "$?" in
   2) eval $(ssh-agent -s); 
      ssh-add;;
   1) ssh-add;;
   0) ;;
esac
	"""

	print commands

if __name__ == '__main__':
	main()
